// .........................................................................
// Title: consolidate_duration.do
//
// Builds consolidated monthly panel of bond durations
// .........................................................................

* --------------------------------------
* Duration panel
* --------------------------------------

* maturities from sec master
use cusip issuance_date maturity_date class_code1 class_code2 using "$raw/cmns/gcap_security_master_cusip", clear
keep if class_code1 == "B"
drop if missing(cusip) | missing(maturity_date)
gsort cusip
save "$tmp/secmaster_maturities", replace

* monthly duration from wrds
use "$raw/wrds/wrds_bond_returns", clear
gen date_m = mofd(DATE)
gsort CUSIP date_m -date
by CUSIP date_m: keep if _n == 1
rename CUSIP cusip
rename DURATION duration
drop if missing(cusip)
keep cusip date_m duration
format %tm date_m
save "$tmp/wrds_duration", replace

* create panel with start and end date observations for each bond, for later tsfill addition
use "$tmp/secmaster_maturities", clear
drop if missing(issuance_date) | missing(maturity_date) | missing(cusip)
drop if issuance_date == maturity_date
keep if class_code2 == "BC"
drop if maturity_date < tm(2005m1)
gen issuer_number = substr(cusip, 1, 6)
expand 2
gsort cusip
by cusip: gen n = _n
assert inlist(n, 1, 2)
gen date_m = mofd(issuance_date) if n == 1
replace date_m = mofd(maturity_date) if n == 2
format %tm date_m
keep cusip date_m
gsort cusip date_m
replace date_m = tm(2020m12) if date_m > tm(2020m12)
bys cusip date_m: keep if _n == 1
count
save "$tmp/maturities_issuances_for_tsfill", replace

* merge duration sources
use "$tmp/ciq_clean_duration", clear
mmerge cusip date_m using "$tmp/wrds_duration", unmatched(m) uname(wrds_)
drop _merge
rename duration ciq_duration
replace wrds_duration = ciq_duration if missing(wrds_duration)
drop ciq_duration
rename wrds_duration duration
rename duration duration_y
gen duration_m = round(duration_y * 12)

* fill in monthly panel
mmerge cusip date_m using "$tmp/maturities_issuances_for_tsfill"
drop if missing(cusip)
egen _cusip = group(cusip)
gsort _cusip date_m
xtset _cusip date_m
count
tsfill
count
by _cusip: carryforward duration_y duration_m, replace
drop _cusip

* merge in maturity dates
mmerge cusip using "$tmp/secmaster_maturities", unmatched(m) ukeep(maturity_date) update
mmerge cusip using "$tmp/ciq_static_characteristics_processed", unmatched(m) ukeep(iq_maturity_date)
drop _merge

* harmonize maturity dates
gen max_maturity = max(iq_maturity_date, maturity_date)
format %td max_maturity
replace maturity_date = max_maturity if ~missing(iq_maturity_date)
drop iq_maturity_date max_maturity
gen maturity_m = mofd(maturity_date)
format %tm maturity_m
gen residual_maturity_m = round(maturity_m - date_m)

* corrections for negative residual maturities
gen neg_maturity_corrected = 1 if residual_maturity_m < 0 & ~missing(residual_maturity_m)
replace neg_maturity_corrected = 0 if missing(neg_maturity_corrected)
replace residual_maturity_m = 0 if residual_maturity_m < 0 & ~missing(residual_maturity_m)
gen residual_maturity_y = residual_maturity_m / 12

* if still missing duration, use residual maturity (zero-coupon assumption)
gen maturity_filled = 0
replace maturity_filled = 1 if missing(duration_y) & ~missing(residual_maturity_y)
replace duration_m = residual_maturity_m if missing(duration_m)
replace duration_y = residual_maturity_y if missing(duration_y)

* save the duration panel
keep cusip date_m duration_* residual_maturity_* maturity_filled neg_
gsort cusip date_m
by cusip date_m: keep if _n == 1
save "$tmp/duration_merged", replace

* duration at quarterly frequency
use "$tmp/duration_merged", clear
gen date_q = qofd(dofm(date_m))
format %tq date_q
gsort cusip date_q -date_m
by cusip date_q: keep if _n == 1
drop date_m
order cusip date_q
save "$tmp/duration_merged_q", replace

* duration at yearly frequency
use "$tmp/duration_merged", clear
gen year = year(dofm(date_m))
gsort cusip year -date_m
by cusip year: keep if _n == 1
drop date_m
order cusip year
save "$tmp/duration_merged_y", replace

* catalog of bonds for which we have duration
use "$tmp/duration_merged", clear
gsort cusip
by cusip: keep if _n == 1
keep cusip
save "$tmp/duration_merged_catalog", replace

* also get issuance dates from sec master
use cusip issuance_date using "$raw/cmns/gcap_security_master_cusip", clear
drop if missing(issuance_date) | missing(issuance_date)
gsort cusip
save "$tmp/secmaster_issuance_dates", replace
